티스토리 뷰

PHP + LARAVEL + Passport

둘 이상의 Guard를 설정하는 것은 라라벨 공식 문서를 통해서 쉽게 확인이 가능하다.
세션과 Passport를 이용한 토큰 인증을 적용하여 router 마다 middleware에 적용하면 쉽게 사용할 수 있다.

기존에 무의식적으로 사용했던 client_credentials은 사용자에 대한 인증이라기 보다 머신(서버)에 대한 인증이라고
보는게 맞다.

 grant_type:Authorization_code를 이용하여 사용하려 했으나, 인증에 대한 middleware 를 동시에 사용하고자 하지만 

기본적으로 하나의 인증이 실패할 경우 다음을 진행하지 않는다.

 

예를 들어

//route.php
Route::get('user', function() {})->middleware(['client','auth:api']);

client_credentialsauthorization_code 를 하나의 컨트롤러에서 이용하여
사용자가 접근하거나 머신이 접근하는 것을 분기하여 처리하고자 하지만 먼저 선언된 인증이 실패 할 경우
그 다음 middleware 를 진행하지 않는다.

 

https://github.com/laravel/passport/issues/898

 

Use middleware 'auth:api' and 'client' simultanaous · Issue #898 · laravel/passport

I use Laravel 5.7.* and Passport ^7.0 . To consume my API with javaScript, I added CreateFreshApiToken middleware. I would also like to implement Client Credentials Grant Tokens authentication so t...

github.com

 

역시나 비슷한 고민을 하는 사람들이 있는 것을 확인할 수 있었다.
두 가지 middleware 를 사용할 수 있는 별도의 미들웨어를 생성하여 처리하는 방법으로 대체 가능하다.

//app\middleware\CheckAPICredentials.php

<?php

namespace App\Http\Middleware;

use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Laravel\Passport\Http\Middleware\CheckClientCredentials;

class CheckAPICredentials extends CheckClientCredentials
{
    /**
     * Validate the scopes and token on the incoming request.
     *
     * @param  \Psr\Http\Message\ServerRequestInterface $psr
     * @param  array  $scopes
     * @return void
     * @throws \Laravel\Passport\Exceptions\MissingScopeException|\Illuminate\Auth\AuthenticationException
     */
    protected function validate($psr, $scopes)
    {
        $token = $this->repository->find($psr->getAttribute('oauth_access_token_id'));
        throw_if(empty($token), exception:"AuthenticationException");

        if (in_array('*', $token->scopes)) {
            return;
        }

        // AuthorizationCode with PKCE guard auth:api
        if (!empty($token->user_id)) {
            Auth::login(User::find($token->user_id));
        }

        foreach ($scopes as $scope) {
            if ($token->cant($scope)) {
                throw new MissingScopeException($scope);
            }
        }
    }
}

#laravel #passport #guard

댓글